Release 10.1A: OpenEdge Development:
Messaging and ESB


DataSetMessage

OpenEdge applications use ProDataSets for data. The new DataSetMessage supports using ProDataSets for JMS messaging. The XMLMessage is the basis for the DataSetMessage. The OpenEdge Adapter for SonicMQ converts the ProDataSet to/from XML and uses the XMLMessage to send/receive ProDataSets. A non-OpenEdge application receives a DataSetMessage as an XMLMessage. The JMS header property signals an OpenEdge application that the incoming message is a DataSetMessage.

For more information on accessing the examples files, see the "Example procedures" section.

For an alphabetical API reference, see Appendix A "4GL-JMS API Reference."

The following example shows sending a DataSetMessage:

dsmsg_send.p
DEFINE VARIABLE ptp AS LOGICAL INITIAL TRUE. 
DEFINE VARIABLE sessionH AS HANDLE. 
DEFINE VARIABLE messageH AS HANDLE. 
DEF VAR hds1 AS HANDLE. 
DEF VAR ret AS LOGICAL NO-UNDO. 
/* Definition for Temp-Table ttCust */ 
DEFINE TEMP-TABLE ttCust NO-UNDO 
    BEFORE-TABLE ttCustBef 
	    FIELD CustNum LIKE Customer.CustNum 
        FIELD Name LIKE Customer.Name COLUMN-LABEL "custlab" 
             XML-NODE-TYPE "Attribute" 
        FIELD Country LIKE Customer.Country 
        FIELD Comments LIKE Customer.Comments FORMAT "x(40)" 
        INDEX CustNum IS PRIMARY UNIQUE CustNum 
        INDEX Name Name 
        INDEX Comments IS WORD-INDEX Comments. 
/* Definition for Temp-Table ttOrder */ 
DEFINE TEMP-TABLE ttOrd 
    FIELD OrderNum LIKE Order.OrderNum 
    FIELD CustNum LIKE Order.CustNum 
    FIELD OrderDate LIKE Order.OrderDate 
    INDEX OrderNum IS PRIMARY UNIQUE OrderNum 
    INDEX CustOrder IS UNIQUE CustNum OrderNum 
    INDEX OrderDate OrderDate. 
DEFINE DATASET myds  
    NAMESPACE-URI "urn:myds" NAMESPACE-PREFIX "ds" 
    FOR ttCust, ttOrd 
    DATA-RELATION custOrd FOR ttCust, ttOrd  
    REPOSITION RELATION-FIELDS (CustNum, CustNum). 
/* Creates a session object. */ 
IF ptp THEN 
    RUN  jms/ptpsession.p PERSISTENT SET sessionH ("-SMQConnect"). 
ELSE 
    RUN  jms/pubsubsession.p PERSISTENT SET sessionH ("-SMQConnect"). 
RUN setBrokerURL IN sessionH ("localhost:2506"). 
RUN beginSession IN sessionH. 
FOR EACH Customer WHERE custNum < 4: 
    CREATE ttCust. 
    BUFFER-COPY Customer TO ttCust. 
    FOR EACH Order OF Customer: 
        CREATE ttOrd. 
        BUFFER-COPY Order TO ttOrd. 
    END. 
END. 
hds1 = DATASET myds:HANDLE. 
/* Uncomment to write XML to a file  
ret = hds1:WRITE-XML("file", "wdsCustOrd.xml", YES, ?,?,YES). 
*/ 
RUN createDatasetMessage in sessionH(OUTPUT messageH). 
RUN setDataSet IN messageH( hds1, ?, TRUE). 
IF ptp THEN 
    RUN sendToQueue IN sessionH ("SampleQ1", messageH, ?, ?, ?).     
ELSE 
    RUN PUBLISH IN sessionH ("TestTopic", messageH, ?, ?, ?). 
     
RUN deleteMessage IN messageH. 
RUN deleteSession in sessionH. 

The following example shows receiving a DataSetMessage:

dsmsg_recv.p
DEFINE VARIABLE ptp AS LOGICAL INITIAL TRUE. 
DEF VAR hds2 AS HANDLE. 
DEF VAR hbuf AS HANDLE. 
DEF VAR hrel AS HANDLE. 
DEF VAR hq AS HANDLE. 
DEF VAR i AS INT. 
DEF VAR j AS INT. 
DEF VAR ret AS LOGICAL NO-UNDO. 
DEFINE VARIABLE sessionH AS HANDLE NO-UNDO. 
DEFINE VARIABLE msgConsumer AS HANDLE NO-UNDO. 
DEFINE VARIABLE mesgH AS HANDLE NO-UNDO. 
DEFINE VARIABLE stillWaiting AS LOGICAL INIT yes. 
DEFINE VARIABLE numRecsRead AS INT NO-UNDO INITIAL 0. 
IF ptp THEN 
    RUN jms/ptpsession.p PERSISTENT SET sessionH ("-SMQConnect"). 
ELSE 
    RUN jms/pubsubsession.p PERSISTENT SET sessionH ("-SMQConnect"). 
RUN setBrokerURL IN sessionH ("localhost:2506"). 
RUN beginSession IN sessionH. 
RUN createMessageConsumer IN sessionH ( 
                              THIS-PROCEDURE,    /* This proc will handle it */ 
                             "messageHandler", /* name of internal procedure */ 
                              OUTPUT msgConsumer). 
IF ptp THEN 
    RUN receiveFromQueue IN sessionH ("SampleQ1", ?, msgConsumer). 
ELSE 
    RUN subscribe IN sessionH ("TestTopic", 
                                ?, /* durable subscription */ 
                                ?, /* No message selector */ 
                                YES, /* Want to get my own publications */ 
                                msgConsumer). 
RUN startReceiveMessages IN sessionH. 
RUN waitForMessages IN sessionH ("inWait", THIS-PROCEDURE, ?). 
RUN deleteSession IN sessionH. 
MESSAGE "Number of records processed: " + STRING(numRecsRead). 
PROCEDURE messageHandler: 
DEFINE INPUT PARAMETER messageH AS HANDLE NO-UNDO. 
DEFINE INPUT PARAMETER messageConsumerH AS HANDLE NO-UNDO. 
DEFINE OUTPUT PARAMETER autoReplyH AS HANDLE NO-UNDO. /* Not used in this 
example */ 
DEFINE VARIABLE ttH1 AS HANDLE NO-UNDO. 
DEFINE VARIABLE bh1 AS HANDLE NO-UNDO. 
DEFINE VARIABLE bh2 AS HANDLE NO-UNDO. 
DEFINE VARIABLE qh1 AS HANDLE NO-UNDO. 
if DYNAMIC-FUNCTION("getMessageType" in messageH) = "DatasetMessage" THEN DO: 
    hds2 = DYNAMIC-FUNCTION("getDataset" IN messageH, ?, ?, ?). 
    numRecsRead = numRecsRead + 1. 
    MESSAGE "num-buffers: " hds2:NUM-BUFFERS "name: " hds2:NAME SKIP 
             "nspace-info: " hds2:NAMESPACE-URI hds2:NAMESPACE-PREFIX  
              VIEW-AS ALERT-BOX. 
MESSAGE "num-relations: " hds2:NUM-RELATIONS VIEW-AS ALERT-BOX. 
    DO i = 1 TO hds2:NUM-RELATIONS: 
        hrel = hds2:GET-RELATION(i). 
        MESSAGE "rel name: " hrel:NAME SKIP 
                "reposition: " hrel:REPOSITION SKIP 
                "nested: " hrel:NESTED SKIP 
                "where-str: " hrel:WHERE-STRING SKIP 
                "parent: " hrel:PARENT-BUFFER:NAME SKIP 
                "child: " hrel:CHILD-BUFFER:NAME SKIP 
                "rel-fields: " hrel:RELATION-FIELDS VIEW-AS ALERT-BOX. 
    END. 
    DO j = 1 TO hds2:NUM-BUFFERS: 
        hbuf = hds2:GET-BUFFER-HANDLE(j). 
        MESSAGE "buf name: " hbuf:NAME VIEW-AS ALERT-BOX. 
            DO i = 1 TO hbuf:NUM-FIELDS: 
                MESSAGE  
                        "name:        " hbuf:BUFFER-FIELD(i):NAME skip 
                        "type:        " hbuf:BUFFER-FIELD(i):DATA-TYPE skip 
                        "extent:      " hbuf:BUFFER-FIELD(i):EXTENT skip 
                        "decimals:    " hbuf:BUFFER-FIELD(i):DECIMALS skip 
                        "xmltype:     " hbuf:BUFFER-FIELD(i):XML-DATA-TYPE skip 
                        "xmlnodetype: " hbuf:BUFFER-FIELD(i):XML-NODE-TYPE skip 
                        "initial:     " hbuf:BUFFER-FIELD(i):INITIAL skip 
                        "format:      " hbuf:BUFFER-FIELD(i):FORMAT skip 
                        "help:        " hbuf:BUFFER-FIELD(i):HELP skip 
                       VIEW-AS ALERT-BOX. 
            END. 
     
    END. 
  CREATE QUERY hq. 
     
    DO j = 1 TO hds2:NUM-BUFFERS: 
        hbuf = hds2:GET-BUFFER-HANDLE(j). 
        MESSAGE "buf name: " hbuf:NAME VIEW-AS ALERT-BOX. 
        hq:SET-BUFFERS(hbuf). 
     
        hq:QUERY-PREPARE("for each " + hbuf:NAME). 
     
        hq:QUERY-OPEN. 
     
        DO WHILE hq:GET-NEXT(): 
            DO i = 1 TO hbuf:NUM-FIELDS: 
                MESSAGE  
                        "name:        " hbuf:BUFFER-FIELD(i):NAME skip 
                        "value:       "  
                        IF  hbuf:BUFFER-FIELD(i):EXTENT > 0 THEN 
                            hbuf:BUFFER-FIELD(i):BUFFER-VALUE[1]  
                        ELSE  
                            hbuf:BUFFER-FIELD(i):BUFFER-VALUE 
                       VIEW-AS ALERT-BOX. 
            END. 
        END. 
     
    END. 
DELETE OBJECT hq. 
    DELETE OBJECT hds2. 
    END. 
ELSE 
    stillWaiting = no. 
RUN deleteMessage IN messageH. 
END PROCEDURE. 
FUNCTION inWait RETURNS LOGICAL. 
RETURN stillWaiting. 
END. 


Copyright © 2005 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095